// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IValueMetadataCollection.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Contract for combining an <typeparamref name="TValue" /> with a <typeparamref name="TMetadata" /> into a <typeparamref name="TValueMetadata" />.
//   Let implementor have an <see cref="ExportAttribute" /> with <see cref="ExportAttribute.ContractType" /> = <see cref="IEnumerable{T}" /> where T is TValueMetadata.
//   <seealso cref="ValueMetadataCollection{TValue,TMetadata,TValueMetadata}" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;

namespace AzureContrib.WindowsAzure
{
	/// <summary>
	/// Contract for combining an <typeparamref name="TValue"/> with a <typeparamref name="TMetadata"/> into a <typeparamref name="TValueMetadata" />.
	/// Let implementor have an <see cref="ExportAttribute"/> with <see cref="ExportAttribute.ContractType"/> = <see cref="IEnumerable{T}"/> where T is TValueMetadata.
	/// </summary>
	/// <typeparam name="TValue">The type of value to compact</typeparam>
	/// <typeparam name="TMetadata">The type of metadata to compact</typeparam>
	/// <typeparam name="TValueMetadata">The resuting combination value-metadata</typeparam>
	[SuppressMessage("Microsoft.Design", "CA1005:AvoidExcessiveParametersOnGenericTypes", Justification = "The whole point here is to merge two types into a combined third. We need three generic parameters.")]
	public interface IValueMetadataCollection<TValue, TMetadata, out TValueMetadata> :
		IEnumerable<TValueMetadata>, ILazyBuilderUser
		where TValueMetadata : TValue, TMetadata
	{
		/// <summary>
		/// Creates a <typeparamref name="TValueMetadata"/> instance from the <see cref="Lazy{T}"/> with T = <typeparamref name="TValue"/> and <typeparamref name="TMetadata"/>.
		/// </summary>
		/// <param name="lazyValueMetadata">The lazy Value Metadata to compact into one instance.</param>
		/// <returns>
		/// The resulting <typeparamref name="TValueMetadata"/> instance.
		/// </returns>
		TValueMetadata Compact(Lazy<TValue, TMetadata> lazyValueMetadata);
	}
}